package com.bzkj.basicinfo.service.impl.warehouse;

import com.bzkj.basicinfo.domain.warehouse.PdaWarehouseInBillsList;
import com.bzkj.basicinfo.domain.warehouse.PdaWarehouseInBillsDetail;
import com.bzkj.basicinfo.mapper.PdaWarehouseInBillsMapper;
import com.bzkj.basicinfo.service.warehouse.IPdaWarehouseInBillsService;
import com.bzkj.basicinfo.service.stock.WmsStockService;
import com.bzkj.basicinfo.service.exception.WmsExceptionRecordService;
import com.bzkj.common.constant.BillStatusConstant;
import com.bzkj.common.core.domain.model.LoginUser;
import com.bzkj.common.core.domain.AjaxResult;
import com.bzkj.common.utils.DateUtils;
import com.bzkj.common.utils.SecurityUtils;
import com.bzkj.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 入库单据Service业务层处理
 * 
 * @author system
 * @date 2025-10-17
 */
@Service
public class PdaWarehouseInBillsServiceImpl implements IPdaWarehouseInBillsService {

    private static final Logger logger = LoggerFactory.getLogger(PdaWarehouseInBillsServiceImpl.class);

    @Resource
    private PdaWarehouseInBillsMapper pdaWarehouseInBillsMapper;

    @Autowired
    private WmsStockService stockService;

    @Autowired
    private WmsExceptionRecordService exceptionRecordService;

    /**
     * 查询入库单据列表
     * 
     * @param billsList 入库单据主表
     * @return 入库单据
     */
    @Override
    public List<PdaWarehouseInBillsList> selectPdaWarehouseInBillsList(PdaWarehouseInBillsList billsList) {
        return pdaWarehouseInBillsMapper.selectPdaWarehouseInBillsList(billsList);
    }

    /**
     * 查询入库单据详情
     * 
     * @param billsID 入库单据主键
     * @return 入库单据
     */
    @Override
    public List<PdaWarehouseInBillsDetail> selectPdaWarehouseInBillsByBillsID(String billsID) {
        return pdaWarehouseInBillsMapper.selectPdaWarehouseInBillsDetailList(billsID);
    }

    /**
     * 新增入库单据
     * 
     * @param billsList 入库单据
     * @return 结果
     */
    @Transactional
    @Override
    public int insertPdaWarehouseInBillsList(PdaWarehouseInBillsList billsList) {
        String currentTime = DateUtils.getTime();
        String currentUser = SecurityUtils.getUsername();

        billsList.setCheckDate(currentTime);
        billsList.setUserId(currentUser);
        // 设置录入人信息
        billsList.setCreatorId(currentUser);
        billsList.setCreatorName(SecurityUtils.getLoginUser().getUser().getNickName());
        billsList.setCreateTime(DateUtils.getNowDate());
        // 设置入库单状态：0-未收货
        billsList.setBillsState(BillStatusConstant.IN_NOT_OPERATED);
        // 默认未拒收
        billsList.setIsRejected("0");

        int rows = pdaWarehouseInBillsMapper.insertPdaWarehouseInBillsList(billsList);
        insertPdaWarehouseInBillsDetail(billsList);
        return rows;
    }

    /**
     * 修改入库单据
     * 
     * @param billsList 入库单据
     * @return 结果
     */
    @Transactional
    @Override
    public int updatePdaWarehouseInBillsList(PdaWarehouseInBillsList billsList) {
        // 删除原有明细
        pdaWarehouseInBillsMapper.deletePdaWarehouseInBillsDetailByBillsID(billsList.getBillsId());
        // 新增明细
        insertPdaWarehouseInBillsDetail(billsList);
        // 修改主表
        return pdaWarehouseInBillsMapper.updatePdaWarehouseInBillsList(billsList);
    }

    /**
     * 批量删除入库单据
     * 
     * @param billsIDs 需要删除的入库单据主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deletePdaWarehouseInBillsByBillsIDs(String[] billsIDs) {
        return pdaWarehouseInBillsMapper.deletePdaWarehouseInBillsByBillsIDs(billsIDs);
    }

    /**
     * 删除入库单据信息
     * 
     * @param billsID 入库单据主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deletePdaWarehouseInBillsByBillsID(String billsID) {
        return pdaWarehouseInBillsMapper.deletePdaWarehouseInBillsByBillsID(billsID);
    }

    /**
     * 新增入库单据明细信息
     *
     * @param billsList 入库单据对象
     */
    private void insertPdaWarehouseInBillsDetail(PdaWarehouseInBillsList billsList) {
        List<PdaWarehouseInBillsDetail> detailList = billsList.getInDetailList();
        String billsId = billsList.getBillsId();
        if (StringUtils.isNotNull(detailList) && detailList.size() > 0) {
            // 计算总件数和总数量
            calculateTotalPackagesAndQuantity(billsList, detailList);

            for (PdaWarehouseInBillsDetail detail : detailList) {
                detail.setBillsId(billsId);
            }
            pdaWarehouseInBillsMapper.batchInsertPdaWarehouseInBillsDetail(detailList);
        }
    }

    /**
     * 提取单据（状态从0变为1）
     *
     * @param billsID 单据号
     * @return 结果
     */
    @Transactional
    @Override
    public int extractBills(String billsID) {
        // 检查当前状态是否为0-未收货
        PdaWarehouseInBillsList currentBills = pdaWarehouseInBillsMapper.selectPdaWarehouseInBillsByBillsID(billsID);
        if (currentBills == null) {
            throw new RuntimeException("单据不存在：" + billsID);
        }

        if (!BillStatusConstant.IN_NOT_OPERATED.equals(currentBills.getBillsState())) {
            throw new RuntimeException("只有未收货状态的单据才能提取，当前状态：" + currentBills.getBillsState());
        }

        PdaWarehouseInBillsList billsList = new PdaWarehouseInBillsList();
        billsList.setBillsId(billsID);
        billsList.setBillsState(BillStatusConstant.IN_EXTRACTED);

        return pdaWarehouseInBillsMapper.updatePdaWarehouseInBillsList(billsList);
    }

    /**
     * 确认验收（状态从1变为2）
     *
     * @param billsID 单据号
     * @return 结果
     */
    @Transactional
    @Override
    public int pdaCompleted(String billsID) {
        // 检查当前状态是否为1-已收货
        PdaWarehouseInBillsList currentBills = pdaWarehouseInBillsMapper.selectPdaWarehouseInBillsByBillsID(billsID);
        if (currentBills == null) {
            throw new RuntimeException("单据不存在：" + billsID);
        }

        if (!BillStatusConstant.IN_EXTRACTED.equals(currentBills.getBillsState())) {
            throw new RuntimeException("只有已收货状态的单据才能完成PDA操作，当前状态：" + currentBills.getBillsState());
        }

        PdaWarehouseInBillsList billsList = new PdaWarehouseInBillsList();
        billsList.setBillsId(billsID);
        billsList.setBillsState(BillStatusConstant.IN_PDA_COMPLETED);
        billsList.setAcceptUserId(String.valueOf(SecurityUtils.getUserId()));
        billsList.setAcceptUserName(SecurityUtils.getUsername());
        billsList.setAcceptTime(DateUtils.getTime());

        return pdaWarehouseInBillsMapper.updatePdaWarehouseInBillsList(billsList);
    }
    /**
     * 确认上架（状态从2变为3，同时更新库存）
     *
     * @param billsID 单据号
     * @return 结果
     */
    @Transactional
    @Override
    public int pdaGrounding(String billsID) {
        // 1. 检查当前状态是否为2-已验收待上架
        PdaWarehouseInBillsList currentBills = pdaWarehouseInBillsMapper.selectPdaWarehouseInBillsByBillsID(billsID);
        if (currentBills == null) {
            throw new RuntimeException("单据不存在：" + billsID);
        }

        if (!BillStatusConstant.IN_PDA_COMPLETED.equals(currentBills.getBillsState())) {
            throw new RuntimeException("只有已验收状态的单据才能上架，当前状态：" + currentBills.getBillsState());
        }

        // 2. 获取单据明细
        List<PdaWarehouseInBillsDetail> detailList = pdaWarehouseInBillsMapper.selectPdaWarehouseInBillsDetailList(billsID);
        if (detailList == null || detailList.isEmpty()) {
            throw new RuntimeException("单据明细为空，无法上架");
        }

        // 3. 判断单据类型，执行库存操作
        String billsType = currentBills.getBillsType();
        boolean isInbound = isInboundType(billsType);

        // 4. 遍历明细，更新库存
        processInventoryOperation(detailList, isInbound);

        // 5. 更新单据状态为已上架
        PdaWarehouseInBillsList billsList = new PdaWarehouseInBillsList();
        billsList.setBillsId(billsID);
        billsList.setBillsState(BillStatusConstant.IN_SIGNED); // 状态3-已上架
        billsList.setShelvingUserId(String.valueOf(SecurityUtils.getUserId()));
        billsList.setShelvingUserName(SecurityUtils.getUsername());
        billsList.setShelvingTime(DateUtils.getTime());

        int rows = pdaWarehouseInBillsMapper.updatePdaWarehouseInBillsList(billsList);

        logger.info("上架成功，库存已更新 - 单据号：{}，上架人：{}，明细数：{}",
                   billsID, SecurityUtils.getUsername(), detailList.size());

        return rows;
    }

    /**
     * 签字操作（状态从2变为3，同时加减库存）
     *
     * @param billsID 单据号
     * @param signUserId 签字人ID
     * @param signUserName 签字人姓名
     * @return 结果
     */
    @Transactional
    @Override
    public int signBills(String billsID, String signUserId, String signUserName) {
        String currentTime = DateUtils.getTime();

        // 1. 查询单据详情，确定单据类型和明细
        PdaWarehouseInBillsList billsList = pdaWarehouseInBillsMapper.selectPdaWarehouseInBillsByBillsID(billsID);
        if (billsList == null) {
            throw new RuntimeException("单据不存在：" + billsID);
        }

        // 检查当前状态是否为2-已验收
        if (!BillStatusConstant.IN_PDA_COMPLETED.equals(billsList.getBillsState())) {
            throw new RuntimeException("只有已验收状态的单据才能签字，当前状态：" + billsList.getBillsState());
        }

        // 2. 根据单据类型判断库存操作
        String billsType = billsList.getBillsType();
        boolean isInbound = isInboundType(billsType);

        // 3. 执行库存操作
        if (billsList.getInDetailList() != null && !billsList.getInDetailList().isEmpty()) {
            processInventoryOperation(billsList.getInDetailList(), isInbound);
        }

        // 4. 更新单据状态
        PdaWarehouseInBillsList updateBills = new PdaWarehouseInBillsList();
        updateBills.setBillsId(billsID);
        updateBills.setBillsState(BillStatusConstant.IN_SIGNED);
        // 使用SecondUser字段存储签字人
        updateBills.setSecondUser(signUserName);
        // 使用Remarks2字段存储签字时间信息
        updateBills.setRemarks2("签字时间：" + currentTime + " 签字人：" + signUserName);

        return pdaWarehouseInBillsMapper.updatePdaWarehouseInBillsList(updateBills);
    }

    /**
     * 判断是否为入库类型单据
     *
     * @param billsType 单据类型
     * @return true-入库，false-出库
     */
    private boolean isInboundType(String billsType) {
        // 入库类型：采购入库、生产入库、退货入库、调拨入库、赠品入库、其他入库
        return "PurchaseWareHouseIn".equals(billsType) ||
               "ProduceWareHouseIn".equals(billsType) ||
               "ReturnWareHouseIn".equals(billsType) ||
               "AllocateWareHouseIn".equals(billsType) ||
               "GiftHouseIn".equals(billsType) ||
               "OtherHouseIn".equals(billsType);
    }

    /**
     * 处理库存操作
     *
     * @param detailList 明细列表
     * @param isInbound 是否为入库
     */
    private void processInventoryOperation(List<PdaWarehouseInBillsDetail> detailList, boolean isInbound) {
        for (PdaWarehouseInBillsDetail detail : detailList) {
            try {
                // 获取确认数量，如果没有则使用原数量
                String quantityStr = StringUtils.isNotEmpty(detail.getDrugCheckNum()) ?
                                   detail.getDrugCheckNum() : detail.getDrugNum();

                if (StringUtils.isEmpty(quantityStr)) {
                    continue; // 跳过没有数量的明细
                }

                BigDecimal quantity = new BigDecimal(quantityStr);

                // 根据是否入库决定库存操作
                if (isInbound) {
                    // 入库：增加库存
                    increaseInventory(detail, quantity);
                } else {
                    // 出库：减少库存
                    decreaseInventory(detail, quantity);
                }

            } catch (NumberFormatException e) {
                // 记录日志，但不阻止其他明细的处理
                logger.warn("处理库存时数量格式错误，单据号：{}，药品：{}，数量：{}",
                           detail.getBillsId(), detail.getDrugName(),
                           StringUtils.isNotEmpty(detail.getDrugCheckNum()) ? detail.getDrugCheckNum() : detail.getDrugNum());
            }
        }
    }

    /**
     * 增加库存
     *
     * @param detail 明细
     * @param quantity 数量
     */
    private void increaseInventory(PdaWarehouseInBillsDetail detail, java.math.BigDecimal quantity) {
        try {
            // 调用库存服务增加库存
            AjaxResult result = stockService.increaseStock(
                detail.getDrugId(),       // 商品ID
                detail.getDrugId(),     // 商品编码
                detail.getDrugName(),     // 商品名称
                detail.getDrugBatchNo(),  // 批次号
                "", // 货位编码（如果有的话）
                quantity,                 // 数量
                "RECEIVE_IN",            // 业务类型：收货入库
                detail.getBillsId(),     // 业务单号
                SecurityUtils.getUsername() // 操作人
            );

            if (!result.isSuccess()) {
                // 库存操作失败，创建异常记录
                String exceptionTitle = "库存增加失败：" + detail.getBillsId();
                String exceptionDesc = "单据[" + detail.getBillsId() + "]增加库存失败，商品：" + detail.getDrugName() +
                                     "，批次：" + detail.getDrugBatchNo() + "，数量：" + quantity +
                                     "，失败原因：" + result.get("msg");

                try {
                    exceptionRecordService.createExceptionRecord(
                        "stock_error",      // 异常类型：库存异常
                        "warehouse_bills",  // 关联单据类型：入库单据
                        detail.getBillsId(), // 关联单据号
                        null,               // 关联单据ID（可选）
                        exceptionTitle,     // 异常标题
                        exceptionDesc,      // 异常描述
                        result.get("msg").toString(),    // 异常原因
                        SecurityUtils.getUsername() // 操作人
                    );
                } catch (Exception e) {
                    logger.error("创建库存异常记录失败", e);
                }

                // 抛出异常，回滚事务
                throw new RuntimeException("增加库存失败：" + result.get("msg"));
            }

            logger.info("增加库存成功 - 药品：{}，批号：{}，数量：{}，仓库：{}",
                       detail.getDrugName(), detail.getDrugBatchNo(), quantity, detail.getStoId());

        } catch (Exception e) {
            logger.error("增加库存异常 - 药品：{}，批号：{}，数量：{}，仓库：{}，错误：{}",
                        detail.getDrugName(), detail.getDrugBatchNo(), quantity, detail.getStoId(), e.getMessage());
            throw new RuntimeException("增加库存异常：" + e.getMessage(), e);
        }
    }

    /**
     * 减少库存
     *
     * @param detail 明细
     * @param quantity 数量
     */
    private void decreaseInventory(PdaWarehouseInBillsDetail detail, java.math.BigDecimal quantity) {
        try {
            // 调用库存服务减少库存
            AjaxResult result = stockService.decreaseStock(
                detail.getDrugId(),       // 商品ID
                detail.getDrugId(),       // 商品编码
                detail.getDrugName(),     // 商品名称
                detail.getDrugBatchNo(),  // 批次号
                "", // 货位编码（如果有的话）
                quantity,                 // 数量
                "WAREHOUSE_OUT",         // 业务类型：仓库出库
                detail.getBillsId(),     // 业务单号
                SecurityUtils.getUsername() // 操作人
            );

            if (!result.isSuccess()) {
                // 库存操作失败，创建异常记录
                String exceptionTitle = "库存减少失败：" + detail.getBillsId();
                String exceptionDesc = "单据[" + detail.getBillsId() + "]减少库存失败，商品：" + detail.getDrugName() +
                                     "，批次：" + detail.getDrugBatchNo() + "，数量：" + quantity +
                                     "，失败原因：" + result.get("msg");

                try {
                    exceptionRecordService.createExceptionRecord(
                        "stock_error",      // 异常类型：库存异常
                        "warehouse_bills",  // 关联单据类型：入库单据
                        detail.getBillsId(), // 关联单据号
                        null,               // 关联单据ID（可选）
                        exceptionTitle,     // 异常标题
                        exceptionDesc,      // 异常描述
                        result.get("msg").toString(),    // 异常原因
                        SecurityUtils.getUsername() // 操作人
                    );
                } catch (Exception e) {
                    logger.error("创建库存异常记录失败", e);
                }

                // 抛出异常，回滚事务
                throw new RuntimeException("减少库存失败：" + result.get("msg"));
            }

            logger.info("减少库存成功 - 药品：{}，批号：{}，数量：{}，仓库：{}",
                       detail.getDrugName(), detail.getDrugBatchNo(), quantity, detail.getStoId());

        } catch (Exception e) {
            logger.error("减少库存异常 - 药品：{}，批号：{}，数量：{}，仓库：{}，错误：{}",
                        detail.getDrugName(), detail.getDrugBatchNo(), quantity, detail.getStoId(), e.getMessage());
            throw new RuntimeException("减少库存异常：" + e.getMessage(), e);
        }
    }

    /**
     * 作废操作（状态变为4）
     *
     * @param billsID 单据号
     * @param reason 作废原因
     * @return 结果
     */
    @Transactional
    @Override
    public int cancelBills(String billsID, String reason) {
        String currentTime = DateUtils.getTime();

        // 首先检查当前单据状态，只有状态为0的单据才能作废
        PdaWarehouseInBillsList currentBills = pdaWarehouseInBillsMapper.selectPdaWarehouseInBillsByBillsID(billsID);
        if (currentBills == null) {
            throw new RuntimeException("单据不存在：" + billsID);
        }

        if (!BillStatusConstant.IN_NOT_OPERATED.equals(currentBills.getBillsState())) {
            throw new RuntimeException("只有未收货状态的单据才能作废，当前状态：" + currentBills.getBillsState());
        }

        PdaWarehouseInBillsList billsList = new PdaWarehouseInBillsList();
        billsList.setBillsId(billsID);
        billsList.setBillsState(BillStatusConstant.IN_CANCELLED);
        // 使用Remarks1字段存储作废原因和时间
        billsList.setRemarks1("作废时间：" + currentTime + " 作废原因：" + reason);

        return pdaWarehouseInBillsMapper.updatePdaWarehouseInBillsList(billsList);
    }

    /**
     * 计算总件数和总数量
     *
     * @param billsList 入库单据对象
     * @param detailList 明细列表
     */
    private void calculateTotalPackagesAndQuantity(PdaWarehouseInBillsList billsList, List<PdaWarehouseInBillsDetail> detailList) {
        java.math.BigDecimal totalPackages = java.math.BigDecimal.ZERO;
        java.math.BigDecimal totalQuantity = java.math.BigDecimal.ZERO;

        for (PdaWarehouseInBillsDetail detail : detailList) {
            // 累计总件数
            if (detail.getDrugJsNum() != null) {
                totalPackages = totalPackages.add(detail.getDrugJsNum());
            }

            // 累计总数量（使用确认数量，如果没有则使用数量）
            String quantity = StringUtils.isNotEmpty(detail.getDrugCheckNum()) ? detail.getDrugCheckNum() : detail.getDrugNum();
            if (StringUtils.isNotEmpty(quantity)) {
                try {
                    totalQuantity = totalQuantity.add(new java.math.BigDecimal(quantity));
                } catch (NumberFormatException e) {
                    // 如果转换失败，忽略该项
                }
            }
        }

        billsList.setTotalPackages(totalPackages);
        billsList.setTotalQuantity(totalQuantity);
    }

    /**
     * 确认收货并拆分批次（状态从0变为1）
     *
     * @param billsID 单据号
     * @param detailList 批次明细列表（包含批次拆分后的明细）
     * @param receiverUserId 收货人ID
     * @param receiverUserName 收货人姓名
     * @return 结果
     */
    @Transactional
    @Override
    public AjaxResult confirmReceiveWithBatch(String billsID, List<PdaWarehouseInBillsDetail> detailList,
                                              String receiverUserId, String receiverUserName) {
        try {
            String currentTime = DateUtils.getTime();

            // 1. 检查当前状态是否为0-未收货
            PdaWarehouseInBillsList currentBills = pdaWarehouseInBillsMapper.selectPdaWarehouseInBillsByBillsID(billsID);
            if (currentBills == null) {
                return AjaxResult.error("单据不存在：" + billsID);
            }

            if (!BillStatusConstant.IN_NOT_OPERATED.equals(currentBills.getBillsState())) {
                return AjaxResult.error("只有未收货状态的单据才能确认收货，当前状态：" + currentBills.getBillsState());
            }

            // 2. 删除原有明细
            pdaWarehouseInBillsMapper.deletePdaWarehouseInBillsDetailByBillsID(billsID);

            // 3. 插入新的批次明细
            if (detailList != null && !detailList.isEmpty()) {
                for (PdaWarehouseInBillsDetail detail : detailList) {
                    detail.setBillsId(billsID);

                    // 设置批次序号和原始标识
                    if (detail.getIsOriginal() == null) {
                        detail.setIsOriginal(0); // 批次拆分产生的明细
                    }

                    // 验证：确认数量和原始数量的合法性
                    String drugNumStr = detail.getDrugNum();
                    String checkNumStr = detail.getDrugCheckNum();

                    if (StringUtils.isEmpty(drugNumStr) || StringUtils.isEmpty(checkNumStr)) {
                        throw new RuntimeException("数量字段不能为空");
                    }

                    try {
                        double originalQty = Double.parseDouble(drugNumStr);
                        double checkQty = Double.parseDouble(checkNumStr);

                        // 验证：确认数量不能为负数
                        if (checkQty < 0) {
                            throw new RuntimeException("药品【" + detail.getDrugName() + "】的确认数量不能为负数");
                        }

                        // 验证：确认数量不能超过原始数量（允许部分收货）
                        if (checkQty > originalQty) {
                            throw new RuntimeException("药品【" + detail.getDrugName() + "】的确认数量(" + checkQty +
                                ")不能超过原始数量(" + originalQty + ")");
                        }

                        logger.debug("收货明细验证通过 - 药品：{}，原始数量：{}，确认数量：{}",
                            detail.getDrugName(), originalQty, checkQty);
                    } catch (NumberFormatException e) {
                        throw new RuntimeException("数量字段必须为数字类型，药品：" + detail.getDrugName());
                    }
                }
                pdaWarehouseInBillsMapper.batchInsertPdaWarehouseInBillsDetail(detailList);
            }

            // 4. 更新主表状态和收货信息
            PdaWarehouseInBillsList updateBills = new PdaWarehouseInBillsList();
            updateBills.setBillsId(billsID);
            updateBills.setBillsState(BillStatusConstant.IN_EXTRACTED); // 状态1
            updateBills.setReceiverUserId(receiverUserId);
            updateBills.setReceiverUserName(receiverUserName);
            updateBills.setReceiveTime(currentTime);

            int rows = pdaWarehouseInBillsMapper.updatePdaWarehouseInBillsList(updateBills);

            logger.info("确认收货成功 - 单据号：{}，收货人：{}，批次数：{}",
                       billsID, receiverUserName, detailList != null ? detailList.size() : 0);

            return rows > 0 ? AjaxResult.success("确认收货成功") : AjaxResult.error("确认收货失败");

        } catch (Exception e) {
            logger.error("确认收货异常 - 单据号：{}，错误：{}", billsID, e.getMessage(), e);
            throw new RuntimeException("确认收货异常：" + e.getMessage(), e);
        }
    }

    /**
     * 收货拒收操作（状态从0变为4）
     *
     * @param billsID 单据号
     * @param rejectReason 拒收原因
     * @param rejectUserId 拒收人ID
     * @param rejectUserName 拒收人姓名
     * @return 结果
     */
    @Transactional
    @Override
    public AjaxResult rejectReceive(String billsID, String rejectReason,
                                   String rejectUserId, String rejectUserName) {
        try {
            String currentTime = DateUtils.getTime();

            // 1. 检查当前状态
            PdaWarehouseInBillsList currentBills = pdaWarehouseInBillsMapper.selectPdaWarehouseInBillsByBillsID(billsID);
            if (currentBills == null) {
                return AjaxResult.error("单据不存在：" + billsID);
            }

            if (!BillStatusConstant.IN_NOT_OPERATED.equals(currentBills.getBillsState())) {
                return AjaxResult.error("只有未收货状态的单据才能拒收，当前状态：" + currentBills.getBillsState());
            }

            // 2. 更新主表状态为异常
            PdaWarehouseInBillsList updateBills = new PdaWarehouseInBillsList();
            updateBills.setBillsId(billsID);
            updateBills.setBillsState(BillStatusConstant.IN_CANCELLED); // 状态4-异常
            updateBills.setIsRejected("1");
            updateBills.setRejectionReason(rejectReason);
            updateBills.setExceptionReason("收货拒收：" + rejectReason);
            updateBills.setExceptionTime(currentTime);
            updateBills.setExceptionUserId(rejectUserId);
            updateBills.setExceptionUserName(rejectUserName);

            int rows = pdaWarehouseInBillsMapper.updatePdaWarehouseInBillsList(updateBills);

            logger.info("收货拒收 - 单据号：{}，拒收原因：{}，操作人：{}", billsID, rejectReason, rejectUserName);

            return rows > 0 ? AjaxResult.success("拒收成功") : AjaxResult.error("拒收失败");

        } catch (Exception e) {
            logger.error("收货拒收异常 - 单据号：{}，错误：{}", billsID, e.getMessage(), e);
            throw new RuntimeException("收货拒收异常：" + e.getMessage(), e);
        }
    }

    /**
     * 查询待验收的单据列表（状态为1-已到货待验收）
     *
     * @param billsList 查询条件
     * @return 入库单据集合
     */
    @Override
    public List<PdaWarehouseInBillsList> selectPendingInspectList(PdaWarehouseInBillsList billsList) {
        billsList.setBillsState(BillStatusConstant.IN_EXTRACTED); // 状态1
        return pdaWarehouseInBillsMapper.selectPdaWarehouseInBillsList(billsList);
    }

    /**
     * 执行验收操作（状态从1变为2）
     *
     * @param billsID 单据号
     * @param detailList 验收明细列表
     * @param acceptUserId 验收人ID
     * @param acceptUserName 验收人姓名
     * @return 结果
     */
    @Transactional
    @Override
    public AjaxResult inspectGoods(String billsID, List<PdaWarehouseInBillsDetail> detailList,
                                   String acceptUserId, String acceptUserName) {
        try {
            String currentTime = DateUtils.getTime();

            // 1. 检查当前状态是否为1-已收货
            PdaWarehouseInBillsList currentBills = pdaWarehouseInBillsMapper.selectPdaWarehouseInBillsByBillsID(billsID);
            if (currentBills == null) {
                return AjaxResult.error("单据不存在：" + billsID);
            }

            if (!BillStatusConstant.IN_EXTRACTED.equals(currentBills.getBillsState())) {
                return AjaxResult.error("只有已到货状态的单据才能验收，当前状态：" + currentBills.getBillsState());
            }

            // 2. 更新明细验收信息
            if (detailList != null && !detailList.isEmpty()) {
                for (PdaWarehouseInBillsDetail detail : detailList) {
                    detail.setQcUserId(acceptUserId);
                    detail.setQcUserName(acceptUserName);
                    detail.setQcDate(currentTime);
                    detail.setStockStatus("1"); // 合格
                    pdaWarehouseInBillsMapper.updatePdaWarehouseInBillsDetail(detail);
                }
            }

            // 3. 更新主表状态
            PdaWarehouseInBillsList updateBills = new PdaWarehouseInBillsList();
            updateBills.setBillsId(billsID);
            updateBills.setBillsState(BillStatusConstant.IN_PDA_COMPLETED); // 状态2
            updateBills.setAcceptUserId(acceptUserId);
            updateBills.setAcceptUserName(acceptUserName);
            updateBills.setAcceptTime(currentTime);

            int rows = pdaWarehouseInBillsMapper.updatePdaWarehouseInBillsList(updateBills);

            logger.info("验收成功 - 单据号：{}，验收人：{}", billsID, acceptUserName);

            return rows > 0 ? AjaxResult.success("验收成功") : AjaxResult.error("验收失败");

        } catch (Exception e) {
            logger.error("验收异常 - 单据号：{}，错误：{}", billsID, e.getMessage(), e);
            throw new RuntimeException("验收异常：" + e.getMessage(), e);
        }
    }

    /**
     * 验收拒收操作（状态从1变为4）
     *
     * @param billsID 单据号
     * @param rejectReason 拒收原因
     * @param acceptUserId 验收人ID
     * @param acceptUserName 验收人姓名
     * @return 结果
     */
    @Transactional
    @Override
    public AjaxResult rejectInspect(String billsID, String rejectReason,
                                   String acceptUserId, String acceptUserName) {
        try {
            String currentTime = DateUtils.getTime();

            // 1. 检查当前状态
            PdaWarehouseInBillsList currentBills = pdaWarehouseInBillsMapper.selectPdaWarehouseInBillsByBillsID(billsID);
            if (currentBills == null) {
                return AjaxResult.error("单据不存在：" + billsID);
            }

            if (!BillStatusConstant.IN_EXTRACTED.equals(currentBills.getBillsState())) {
                return AjaxResult.error("只有已到货状态的单据才能拒收，当前状态：" + currentBills.getBillsState());
            }

            // 2. 更新主表状态为异常
            PdaWarehouseInBillsList updateBills = new PdaWarehouseInBillsList();
            updateBills.setBillsId(billsID);
            updateBills.setBillsState(BillStatusConstant.IN_CANCELLED); // 状态4-异常
            updateBills.setIsRejected("1");
            updateBills.setRejectionReason(rejectReason);
            updateBills.setExceptionReason("验收不通过：" + rejectReason);
            updateBills.setExceptionTime(currentTime);
            updateBills.setExceptionUserId(acceptUserId);
            updateBills.setExceptionUserName(acceptUserName);

            int rows = pdaWarehouseInBillsMapper.updatePdaWarehouseInBillsList(updateBills);

            logger.info("验收拒收 - 单据号：{}，拒收原因：{}，验收人：{}", billsID, rejectReason, acceptUserName);

            return rows > 0 ? AjaxResult.success("拒收成功") : AjaxResult.error("拒收失败");

        } catch (Exception e) {
            logger.error("验收拒收异常 - 单据号：{}，错误：{}", billsID, e.getMessage(), e);
            throw new RuntimeException("验收拒收异常：" + e.getMessage(), e);
        }
    }

    /**
     * 查询待上架的单据列表（状态为2-验收完成待上架）
     *
     * @param billsList 查询条件
     * @return 入库单据集合
     */
    @Override
    public List<PdaWarehouseInBillsList> selectPendingShelvingList(PdaWarehouseInBillsList billsList) {
        billsList.setBillsState(BillStatusConstant.IN_PDA_COMPLETED); // 状态2
        return pdaWarehouseInBillsMapper.selectPdaWarehouseInBillsList(billsList);
    }

    /**
     * 上架异常操作（状态从2变为4）
     *
     * @param billsID 单据号
     * @param exceptionReason 异常原因
     * @param shelvingUserId 上架人ID
     * @param shelvingUserName 上架人姓名
     * @return 结果
     */
    @Transactional
    @Override
    public AjaxResult shelvingException(String billsID, String exceptionReason,
                                       String shelvingUserId, String shelvingUserName) {
        try {
            String currentTime = DateUtils.getTime();

            // 1. 检查当前状态
            PdaWarehouseInBillsList currentBills = pdaWarehouseInBillsMapper.selectPdaWarehouseInBillsByBillsID(billsID);
            if (currentBills == null) {
                return AjaxResult.error("单据不存在：" + billsID);
            }

            if (!BillStatusConstant.IN_PDA_COMPLETED.equals(currentBills.getBillsState())) {
                return AjaxResult.error("只有验收完成状态的单据才能记录上架异常，当前状态：" + currentBills.getBillsState());
            }

            // 2. 更新主表状态为异常
            PdaWarehouseInBillsList updateBills = new PdaWarehouseInBillsList();
            updateBills.setBillsId(billsID);
            updateBills.setBillsState(BillStatusConstant.IN_CANCELLED); // 状态4-异常
            updateBills.setExceptionReason("上架异常：" + exceptionReason);
            updateBills.setExceptionTime(currentTime);
            updateBills.setExceptionUserId(shelvingUserId);
            updateBills.setExceptionUserName(shelvingUserName);

            int rows = pdaWarehouseInBillsMapper.updatePdaWarehouseInBillsList(updateBills);

            logger.info("上架异常 - 单据号：{}，异常原因：{}，操作人：{}", billsID, exceptionReason, shelvingUserName);

            return rows > 0 ? AjaxResult.success("已记录上架异常") : AjaxResult.error("记录上架异常失败");

        } catch (Exception e) {
            logger.error("记录上架异常失败 - 单据号：{}，错误：{}", billsID, e.getMessage(), e);
            throw new RuntimeException("记录上架异常失败：" + e.getMessage(), e);
        }
    }
}

